package com.tianyu.jty.common.service.impl;

import com.tianyu.jty.common.service.IBaseNativeQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.math.BigDecimal;
import java.sql.*;
import java.util.*;

@Service
public class BaseNativeQueryImpl implements IBaseNativeQuery {

    @Resource(name = "dataSource")
    DataSource ds;

    private static Logger logger = LoggerFactory.getLogger(BaseNativeQueryImpl.class);

    public List<Map<String, Object>> searchForList(String sql, List<?> params) {
        return this.searchForList(sql, params, true);
    }

    public List<Map<String, Object>> searchForList(String sql, List<?> params, boolean beanStyleColName) {
        ArrayList<Map<String, Object>> list = new ArrayList(32);
        Connection conn = null;
        try {
            conn = this.getConnection();
            PreparedStatement pstmt = conn.prepareStatement(sql);
            int i = 1;
            if (params != null) {
                for (Iterator i$ = params.iterator(); i$.hasNext(); ++i) {
                    Object o = i$.next();
                    pstmt.setObject(i, o);
                }
            }

            long l1 = System.currentTimeMillis();
            ResultSet rs = pstmt.executeQuery();
            ResultSetMetaData rsMeta = rs.getMetaData();
            int columnCount = rsMeta.getColumnCount();

            while (rs.next()) {
                HashMap<String, Object> row = new HashMap(columnCount * 4 / 3);
                for (int j = 1; j <= columnCount; ++j) {
                    String colName = rsMeta.getColumnName(j);
                    row.put(beanStyleColName ? toBeanStyleCol(colName) : colName.toLowerCase(), rs.getObject(colName));
                }
                list.add(row);
            }

            rs.close();
            pstmt.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return list;
    }

    public Map<String, Object> searchForObject(String sql, List<?> params) {
        return this.searchForObject(sql, params, true);
    }

    public Map<String, Object> searchForObject(String sql, List<?> params, boolean beanStyleColName) {
        ArrayList<Map<String, Object>> list = new ArrayList(32);
        Connection conn = null;
        try {
            conn = this.getConnection();
            PreparedStatement pstmt = conn.prepareStatement(sql);
            int i = 1;
            if (params != null) {
                for (Iterator i$ = params.iterator(); i$.hasNext(); ++i) {
                    Object o = i$.next();
                    pstmt.setObject(i, o);
                }
            }

            long l1 = System.currentTimeMillis();
            ResultSet rs = pstmt.executeQuery();
            ResultSetMetaData rsMeta = rs.getMetaData();
            int columnCount = rsMeta.getColumnCount();

            while (rs.next()) {
                HashMap<String, Object> row = new HashMap(columnCount * 4 / 3);
                for (int j = 1; j <= columnCount; ++j) {
                    String colName = rsMeta.getColumnName(j);
                    row.put(beanStyleColName ? toBeanStyleCol(colName) : colName.toLowerCase(), rs.getObject(colName));
                }
                list.add(row);
            }

            rs.close();
            pstmt.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }
        }
        return (list!=null && list.size()>0)?list.get(0):new HashMap<String, Object>();
    }

    public Connection getConnection() {
        try {
            return ds.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException("获取数据库连接失败", e);
        }
    }

    private static String toBeanStyleCol(String colName) {
        StringBuilder sb = new StringBuilder();
        String[] str = colName.toLowerCase().split("_");
        int i = 0;
        for (String s : str) {
            if (s.length() == 1)
                s = s.toUpperCase();
            i++;
            if (i == 1) {
                sb.append(s);
                continue;
            }
            if (s.length() > 0) {
                sb.append(s.substring(0, 1).toUpperCase());
                sb.append(s.substring(1));
            }
        }
        return sb.toString();
    }

}
